package tools;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.zip.ZipEntry;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;

import com.lexicalscope.jewel.cli.CliFactory;
import com.lexicalscope.jewel.cli.Option;

/**
 * Hello world!
 */
public class ImportChain {
	private static Params params;

	public static void main(String[] args) throws IOException {
		params = CliFactory.parseArguments(Params.class, args);

		browse(0, params.getFolder(), params.getRoot());
	}

	private static void browse(int indent, String folder, String rootContextPath)
			throws IOException {
		// indent
		for (int i = 0; i < indent; i++)
			System.out.print(".");
		System.out.print(rootContextPath + "  ");

		String rootJarName = rootContextPath.split(":")[0];
		String rootPath = rootContextPath.split(":")[1];

		JarFile rootJar = new JarFile(folder + "/" + rootJarName);
		JarEntry jarEntry = rootJar.getJarEntry(rootPath);
		String context = IOUtils.toString(rootJar.getInputStream(jarEntry));

		List<String> imports = getImports(context);
		for (String s : imports) {
			List<String> next = getJars(s);
			for (String child : next) {
				// ex: child="a.jar:org/apache/toto.xml"
				browse(indent + 4, folder, child);
			}
		}
	}

	/**
	 * @return "a.jar:org/apache/toto.xml","a.jar:org/apache/to.xml"
	 */
	private static List<String> getJars(String fileName) throws IOException {
		List<String> jars = new ArrayList<String>();
		File folder = new File(params.getFolder());
		for (File file : FileUtils.listFiles(folder, null, true)) {
			if (file.getName().endsWith(".jar")) {
				JarFile jar = new JarFile(file);
				ZipEntry entry = jar.getEntry(fileName);
				if (entry != null) {
					jars.add(file.getName() + ":" + entry.getName());
				}
			}
		}
		return jars;
	}

	/**
	 * @return "org/apache/toto.xml","org/apache/to.xml"
	 */
	private static List<String> getImports(String context) {
		System.out.print("{");

		if (params.getBean() != null
				&& context.contains("\"" + params.getBean() + "\"")) {
			System.out.print(params.getBean().toUpperCase() + ",");
		}
		List<String> imports = new ArrayList<String>();
		Pattern pattern = Pattern
				.compile("\\<import\\s+resource\\s*=\\s*\"classpath\\**:/(.+?)\"");
		Matcher matcher = pattern.matcher(context);

		while (matcher.find()) {
			System.out.print(matcher.group(1) + ",");
			imports.add(matcher.group(1));
		}
		System.out.println("}");
		return imports;
	}

	public static interface Params {
		@Option
		String getRoot();

		@Option(defaultValue = ".")
		String getFolder();

		@Option(defaultToNull = true)
		String getBean();
	}
}
